/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2008 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;

using Galaxium.Core;
using Galaxium.Protocol;

using Anculus.Core;

namespace Galaxium.Client
{
	public class GeneralSession : AbstractSession
	{
	//	CHECKTHIS
	//	bool _disposed;
		ContactCollection _contacts;
		GroupCollection _groups;
		
		public override ContactCollection ContactCollection
		{
			get { return _contacts; }
		}
		
		public override GroupCollection GroupCollection
		{
			get { return _groups; }
		}
		
		public GeneralSession (GeneralAccount account) : base (account)
		{
			_contacts = new ContactCollection ();
			_groups = new GroupCollection ();
			
			SessionUtility.SessionAdded += SessionAdded;
			SessionUtility.SessionRemoved += SessionRemoved;
			
			EmitLoginCompleted (new SessionEventArgs (this));
		}
		
		protected override void Dispose (bool disposing)
		{
			// CHECKTHIS
		//	_disposed = true;
		}
		
		public override void Connect ()
		{
			OnConnected (new SessionEventArgs (this));
		}
		
		public override void Disconnect ()
		{
			OnDisconnected (new SessionEventArgs (this));
		}
		
		public override void SetPresence (BasePresence presence)
		{
			
		}
		
		void SessionAdded (object sender, SessionEventArgs args)
		{
			// When a session is added, we want to incorporate its contacts and groups
			// into the general collection
			
			foreach (IGroup group in args.Session.GroupCollection)
			{
				//Log.Debug ("Group added");
				_groups.Add (group);
				EmitGroupAdded (new GroupEventArgs (group));
			}
			
			foreach (IContact contact in args.Session.ContactCollection)
			{
				// CHECKTHIS
			//	bool grouped = false;
				
				foreach (IGroup group in args.Session.GroupCollection)
				{
					if (group.Contains (contact))
					{
						//Log.Debug ("Contact added");
						_contacts.Add (contact);
						EmitContactAdded (new ContactListEventArgs (contact, group));
					}
				}
			}
			
			args.Session.ContactAdded += SessionContactAdded;
			args.Session.ContactRemoved += SessionContactRemoved;
			args.Session.ContactChanged += SessionContactChanged;
			args.Session.GroupAdded += SessionGroupAdded;
			args.Session.GroupRemoved += SessionGroupRemoved;
			args.Session.GroupRenamed += SessionGroupRenamed;
		}
		
		void SessionRemoved (object sender, SessionEventArgs args)
		{
			// When a session is removed, we want to remove all the contacts and groups
			// from the general collection
			
			foreach (IGroup group in args.Session.GroupCollection)
				_groups.Remove (group);
			
			foreach (IContact contact in args.Session.ContactCollection)
				_contacts.Remove (contact);
			
			args.Session.ContactAdded -= SessionContactAdded;
			args.Session.ContactRemoved -= SessionContactRemoved;
			args.Session.ContactChanged -= SessionContactChanged;
			args.Session.GroupAdded -= SessionGroupAdded;
			args.Session.GroupRemoved -= SessionGroupRemoved;
			args.Session.GroupRenamed -= SessionGroupRenamed;
		}
		
#region Session event handlers
		void SessionContactAdded (object sender, ContactListEventArgs args)
		{
			EmitContactAdded (args);
		}
		
		void SessionContactRemoved (object sender, ContactListEventArgs args)
		{
			EmitContactRemoved (args);
		}
		
		void SessionContactChanged (object sender, ContactEventArgs args)
		{
			EmitContactChanged (args);
		}
		
		void SessionGroupAdded (object sender, GroupEventArgs args)
		{
			EmitGroupAdded (args);
		}
		
		void SessionGroupRemoved (object sender, GroupEventArgs args)
		{
			EmitGroupRemoved (args);
		}
		
		void SessionGroupRenamed (object sender, GroupEventArgs args)
		{
			EmitGroupRenamed (args);
		}
#endregion
	}
}
